<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p>a:{{a}}</p>
        <!-- <p>doubleA:{{doubleA}}</p> -->
        <p>
            <button @click="addA">a++</button>
            <button @click="reduceA">a--</button>
        </p>
    </div>
</body>
<script type="module">
    // 整体载入  => 查看模块内暴露的变量和方法
    import * as Vue from "../js/vue.esm-browser.js"; 
    console.log(Vue);

    // 按需引入
    import {createApp,ref} from  "../js/vue.esm-browser.js"; 


    // 组合式写法 可以理解为是选项式语法的优化, 但是最终还是会被解析成选项式语法
    // 在 setup() 函数中返回的对象会暴露给模板和组件实例。其他的选项也可以通过组件实例来获取 setup() 暴露的属性
    let app = createApp({
        setup(){
            console.log("setup 组合式函数");
            // 1. 组合式函数setup 发生在Vue实例创建后, 配置对象解析之前 => 此时无法访问this,也无法使用Vue选项式语法中的data methods computed 等等
            // 2. setup函数要求返回一个对象(可以存储数据(data),方法(methods), 计算属性(computed),声明周期钩子函数) =>会暴露给模板(可以在模版语法中使用)和组件实例(最终还是存储的vue实例上) 
            // 3. 可以理解为组合式写法 只是提前注册了 数据(data),方法(methods), 计算属性(computed),声明周期钩子函数 => 最终还是存储的vue实例上


            // 当前写法有问题  
            // 1. 通过打印发现变量已经修改了,但是视图没有更新 !!!
            // 2. 分析 vue响应式无法检测变量改变,进而无法更新视图   => 问:怎么变成响应式
            // let a = 1;    // 变量 => 值类型
            // function addA(){
            //     a++;
            //     console.log(a);
            // }
            // function reduceA(){
            //     a--;
            //     console.log(a);
            // }

            /* 
                ref()  =>  创建一个对值类型的引用 (一般用于存储 值类型 string number boolean null undefined , 数组对象也可以)
                1. 通过ref()方法 创建ref对象, 对象中存在value属性,存储传入的值 
                2. 当通过ref对象的value属性进行赋值时,会被vue响应式检测到  => 进而更新视图  
                3. 在setup函数中,修改ref对象 需要借助.value属性
                4. 在vue对应的proxy代理对象和模版语法中使用时, 不需要加.value属性 => 官方会有一个解包操作
                

                const myRef = {
                    _value: 0,
                    get value() {
                        track()  // 订阅操作  => 所有依赖当前数据的其他数据, 都是当前数据的订阅者
                        return this._value
                    },
                    set value(newValue) {
                        this._value = newValue
                        trigger();  // 当数据被修改之后 更新视图,触发副作用操作(如果有其他数据依赖(订阅)当前数据,触发对应的副作用操作)
                    }
                }
            
            */
            

            let a = ref(1);
            console.log(a);

            function addA(){
                a.value++;
                console.log(a.value);
            }
            function reduceA(){
                a.value--;
                console.log(a.value);
            }


            return {
                a:a,
                addA:addA,
                reduceA:reduceA,
            }

        },
        beforeCreate() {
            console.log("beforeCreate");
        },
        created() {
            console.log("created");
        },
        beforeMount() {
            console.log("beforeMount");
        },
        mounted() {
            console.log("mounted",this);

            /* 
                this => Proxy代理对象(模拟)
                Proxy => {   // 写法只是方便理解
                    get a(){
                        return a.value;
                    }
                    set a(val){
                        a.value = val;
                    }
                }

            
            
            */
        },
    })

    app.mount("#app");
</script>
</html>